package server;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Logs all activity of the ACE server
 */
public class Logger {
	public static final String dateFormat = "yyyy.MM.dd HH:mm:ss";
	public static final String logDir = "logs";
	public static final String logFileName = "log";
	public static final long logMaxSize = 1280000; 
	private SimpleDateFormat formatter;
	private int logLevel;
	private int errorLevel;
	private File logFile;
	
	private Logger() {
		formatter = new SimpleDateFormat(dateFormat);
		logFile = getLatestFile();
		logLevel = 5;
		errorLevel = 5;
	}
	
	public void addLog(String msg, int level) {
		if (level <= logLevel) {
			String log = getTime()+" >> ("+level+") - "+msg;
			System.out.println(log);
			addToFile(log,level);
		}
	}
	
	public void addError(String msg, int level) {
		if (level <= errorLevel) {
			String log = getTime()+" >> ("+level+") - "+msg;
			System.err.println(log);
			addToFile(log,level);
		}
	}
	
	public void addSQLQueryError(String msg, String query, int level) {
		if (level <= errorLevel) {
			String log = getTime()+" >> ("+level+") - "+msg;
			log += "\n"+"\tQUERY = "+query;
			System.err.println(query);
			addToFile(log,level);
		}
	}
	
	private String getTime() {
		return formatter.format(new Date(System.currentTimeMillis()));
	}
	
	
	private final File getLatestFile() {
		File dir = new File(Logger.logDir);
		File file;
		int index = -1;
		boolean complete = false;
		StringTokenizer token;
		String current;
		if(!dir.exists())
			dir.mkdir();
		String[] files = dir.list();	
		for(int i=0; i<files.length; i++){
			if(files[i].startsWith(logFileName)){
				file = new File(logDir+"/"+files[i]);
				if(file.length() < logMaxSize)
					return file;
				token = new StringTokenizer(files[i],".");
				while(!complete){
					current=token.nextToken();
					if(Integer.getInteger(current) >= index){
						index = Integer.getInteger(current);
					}
				}
			}
		}
		index++;
		try{
			file = new File(logDir+"/"+logFileName +"."+index);
			file.createNewFile();
			return file;
		} catch (IOException e) {
			return null;
	    }
	}
	
	private boolean addToFile(String line, int level){
		if(logFile.length()>=logMaxSize){
			logFile = getLatestFile();
		}
		try{
			FileWriter writer = new FileWriter(logFile, true);
			writer.write(line+"\n");
			writer.close();
		} catch(IOException e){
			return false;
		}
		return true;
	}
	
	public int getLogLevel() { return logLevel; }
	public void setLogLevel(int newLevel) { logLevel = newLevel; }
	
	public int getErrorLevel() { return errorLevel; }
	public void setErrorLevel(int newLevel) { errorLevel = newLevel; }
	
	
	/*
	 * Holds only logger object
	 */
	private static class LoggerHolder { 
		private final static Logger INSTANCE = new Logger();
	}
 
	public static Logger getInstance() {
		return LoggerHolder.INSTANCE;
	}
}
